#!/usr/bin/env python
#######
## AVBot, written by Austin (Eulalia459678)
## using the Python Twisted framework, and built off of Twisted's example logbot, ircLogBot.py
######
## Planned features: Logging, others coming soon
##
#######

from twisted.words.protocols import irc
from twisted.internet import reactor, protocol
from twisted.python import log
from Utils import readConfig # Stolen from pgkbot :D
import time, sys, os, re

trigger  = "&"
version  = "0.1"
trigger  = "&"
nickname = "AVBot"
users    = ["j00lalia", "charitwo"]

class MessageLogger:
	"""
	An independent logger class (because separation of application
	and protocol logic is a good thing).
	"""
	def __init__(self, file):
		self.file = file

	def log(self, message):
		"""Write a message to the file."""
		timestamp = time.strftime("[%H:%M:%S]", time.localtime(time.time()))
		self.file.write('%s %s\n' % (timestamp, message))
		self.file.flush()

	def close(self):
		self.file.close()

class AVBot(irc.IRCClient):
	"""Main class of the bot"""
	
	nickname = "AVBot"

	def connectionMade(self):
		irc.IRCClient.connectionMade(self)
		self.logger = MessageLogger(open(self.factory.filename, "a"))
		self.logger.log("[connected at %s]" % 
			time.asctime(time.localtime(time.time())))

	def connectionLost(self, reason):
		irc.IRCClient.connectionLost(self, reason)
		self.logger.log("[disconnected at %s]" % 
			time.asctime(time.localtime(time.time())))
		self.logger.close()

	def signedOn(self):
		"""Called when bot connects."""
		self.join(self.factory.channel)
		if "password" in self.factory.config:
			self.logger.log("Sending NickServ Password . . .")
			self.msg("NickServ","identify %s" % self.factory.config['password']) 

	def joined(self, channel):
		"""Called when bot joins channel."""
		self.logger.log("[Joined %s]" % channel)

	def privmsg(self, user, channel, msg):
		"""This will get called when the bot receives a message."""
		user = user.split('!', 1)[0]
		self.logger.log("<%s> %s" % (user, msg))

		if channel == self.nickname:
			msg = "Please send all messages in-channel, rather than in a pm. Thanks!"
			self.msg(user, msg)
			return
		
		if msg.startswith(trigger + self.nickname):
			user = user.split('!', 1)[0]
			if user in users:
				msg = "Success! Nick works."
			else:
				msg = "Not authorized."
			self.msg(channel, msg)
			self.logger.log("<%s> %s" % (self.nickname, msg))

		if msg.startswith(trigger + "version"):
			msg = "%s, version %s" % (nickname, version)
			self.msg(channel, msg)
			self.logger.log("<%s> %s" % (self.nickname, msg))

		if msg.startswith(nickname + ", lol"):
			msg = "lol"
			self.msg(channel, msg)
			self.logger.log("<%s> %s"% (self.nickname, msg))

		if msg.startswith(trigger + "die"):
			host = user.split('!', 1)[2] 
			if host == "wikia/Eulalia459678":
				connector.disconnect()
	
	def action(self, user, channel, message):
		"""Called when bot sees someone perform an action."""
		user = user.split('!', 1)[0]
		self.logger.log("* %s %s" % (user, msg))

	def irc_NICK(self, prefix, params):
		"""Called when a user changes nicks."""
		old_nick = prefix.split('!')[0]
		new_nick = params[0]
		self.logger.log("%s is now known as %s" % (old_nick, new_nick))

	def alterCollidedNick(self, nickname):
		"""
		Generate an altered version of a nickname that caused a collision in an
		effort to create an unused related name for subsequent registration.
		"""
		return nickname + '^'

class AVBotFactory(protocol.ClientFactory):
	"""
	A new protocol instance will be created each time we connect to the server.
	"""
	
	protocol = AVBot
	
	def __init__(self, channel, filename):
		self.channel = channel
		self.filename = filename
		self.config = readConfig("Config/AVBot.conf")
	
	def clientConnectionLost(self, connector, reason):
		"""If we get disconnected, reconnect automagically."""
		connector.connect()

	def clientConnectionFailed(self, connector, reason):
		print "Connection failed. Reason: ", reason
		reactor.stop()

if __name__ == '__main__':
	# initialize logging
	log.startLogging(sys.stdout)
    
	# create factory protocol and application
	f = AVBotFactory(sys.argv[1], sys.argv[2])

	# connect factory to this host and port
	reactor.connectTCP("irc.freenode.net", 6667, f)

	# run bot
	reactor.run()
